package cn.iluwen.airline.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * 密码加密工具类
 * 使用SHA-256算法和随机盐值实现密码加密和验证
 */
public class BCrypt {
    private static final int SALT_LENGTH = 16; // 盐值长度
    private static final String ALGORITHM = "SHA-256";
    private static final String SEPARATOR = "$"; // 用于分隔盐值和哈希值的分隔符
    
    /**
     * 加密密码
     * @param rawPassword 原始密码
     * @return 加密后的密码（格式：盐值$哈希值）
     */
    public static String encrypt(String rawPassword) {
        try {
            // 生成随机盐值
            SecureRandom random = new SecureRandom();
            byte[] salt = new byte[SALT_LENGTH];
            random.nextBytes(salt);
            
            // 计算哈希值
            MessageDigest md = MessageDigest.getInstance(ALGORITHM);
            md.update(salt);
            md.update(rawPassword.getBytes());
            byte[] hash = md.digest();
            
            // 将盐值和哈希值编码为Base64并拼接
            String saltBase64 = Base64.getEncoder().encodeToString(salt);
            String hashBase64 = Base64.getEncoder().encodeToString(hash);
            
            return saltBase64 + SEPARATOR + hashBase64;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("加密算法不可用", e);
        }
    }
    
    /**
     * 比较密码
     * @param rawPassword 原始密码
     * @param encodedPassword 加密后的密码
     * @return 是否匹配
     */
    public static boolean matches(String rawPassword, String encodedPassword) {
        try {
            // 分解存储的密码，获取盐值和哈希值
            String[] parts = encodedPassword.split("\\" + SEPARATOR);
            if (parts.length != 2) {
                return false; // 格式不正确
            }
            
            byte[] salt = Base64.getDecoder().decode(parts[0]);
            byte[] expectedHash = Base64.getDecoder().decode(parts[1]);
            
            // 使用相同的盐值计算输入密码的哈希值
            MessageDigest md = MessageDigest.getInstance(ALGORITHM);
            md.update(salt);
            md.update(rawPassword.getBytes());
            byte[] actualHash = md.digest();
            
            // 比较哈希值
            return MessageDigest.isEqual(expectedHash, actualHash);
        } catch (Exception e) {
            return false; // 解码或计算出错，视为不匹配
        }
    }
} 